package com.crm.aspect;

import cn.hutool.core.date.DateUtil;
import cn.hutool.http.useragent.UserAgent;
import cn.hutool.http.useragent.UserAgentUtil;
import com.crm.domain.dto.LoginDTO;
import com.crm.domain.entity.LoginHistory;
import com.crm.service.LoginHistoryService;
import com.crm.utils.NetworkUtil;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.util.Objects;


/**
 * 登录日志切面
 *
 * @author wb
 * @since 2024-07-01
 */

@Aspect
@Component
public class LoginAspect {


    @Autowired
    private LoginHistoryService loginHistoryService;


    /**
     * 切点
     */
    @Pointcut("execution(* com.crm.service.UserService.login(..))")
    public void loginPointcut() {
        System.out.println("login 切点");
    }

    /**
     * 后置通知
     *
     * @param joinPoint 连接点
     * @param result    返回结果
     */
    @AfterReturning(pointcut = "loginPointcut()", returning = "result")
    public void afterLogin(JoinPoint joinPoint, Object result) {
        System.out.println("after result ===> " + result);
        LoginDTO loginDTO = (LoginDTO) joinPoint.getArgs()[0];
        recordLoginHistory(loginDTO.getUsername(), 2, "登录成功");

    }

    /**
     * 异常通知
     *
     * @param joinPoint 连接点
     * @param e         异常
     */
    @AfterThrowing(pointcut = "loginPointcut()", throwing = "e")
    public void afterThrowing(JoinPoint joinPoint, Exception e) {
        LoginDTO loginDTO = (LoginDTO) joinPoint.getArgs()[0];
        recordLoginHistory(loginDTO.getUsername(), 1, e.getMessage());
    }


    /**
     * 记录登录日志
     *
     * @param username
     * @param status
     * @param description
     */
    private void recordLoginHistory(String username, Integer status, String description) {
        LoginHistory loginHistory = new LoginHistory();
        loginHistory.setUsername(username);
        loginHistory.setIp(NetworkUtil.getIp());
        loginHistory.setProvince(NetworkUtil.getProvince());
        loginHistory.setCity(NetworkUtil.getCity());

        HttpServletRequest request = ((ServletRequestAttributes) Objects.requireNonNull(RequestContextHolder.getRequestAttributes())).getRequest();
        UserAgent userAgent = UserAgentUtil.parse(request.getHeader("User-Agent"));

        loginHistory.setDriverName(userAgent.getBrowser() + " " + userAgent.getVersion());
        loginHistory.setOsName(userAgent.getOs().getName().substring(0, userAgent.getOs().getName().indexOf("or")));
        loginHistory.setStatus(status);
        loginHistory.setDescription(description);
        loginHistory.setCreateDate(DateUtil.now());

        loginHistoryService.insert(loginHistory);
    }
}
